"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => general settings
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
if (has('win32') || has('win64') || has('win32unix'))
    let b:IsWin = 1
else
    let b:IsWin = 0
endif
set nocompatible
set nobackup
set nowritebackup
set noswapfile
set hidden

set fileformats=unix,dos,mac
set fileformat=unix
set encoding=utf-8
set fileencoding=utf-8
set fileencodings=ucs-bom,utf-8,gbk,gb18030,big5,euc-jp,latin1
let $LANG='en'
set langmenu=en
set guifont=Maple\ Mono\ Normal\ NF\ CN:h10
if b:IsWin == 1
    if has('nvim')
        let g:python3_host_prog='d:\develop\python\python.exe'
    else
        set pythonthreedll=d:\develop\python\python3.dll
        set pythonthreehome=d:\develop\python
        set luadll=d:\develop\lua\lua54.dll
    endif
else
    if stridx($PATH, 'clangd/bin') < 0
        let $PATH .= ':' . '/opt/clangd/bin'
    endif
    if stridx($PATH, 'node/bin') < 0
        let $PATH .= ':' . '/opt/node/bin'
    endif
    if has('nvim')
        let g:python3_host_prog = '/opt/miniconda/envs/py311/bin/python3'
        let g:perl_host_prog = '/usr/bin/perl'
        let g:ruby_host_prog = '/usr/bin/ruby'
    endif
endif
filetype on
filetype plugin on
filetype indent on

set expandtab
set shiftwidth=4
set tabstop=4
set softtabstop=4
set smarttab
set autoindent
set smartindent
set linebreak
set textwidth=0
set cindent
set wrap
set completeopt=menu,preview
set showtabline=0

set guioptions-=T
set guioptions-=m
if !has('nvim') && has('gui_running')
    set termencoding=utf-8
    set guioptions+=b
    set guioptions+=l
    set guioptions+=L
    set guioptions+=r
    set guioptions+=R
    if b:IsWin == 1
        set columns=120
        set lines=40
        winpos 400 10
    else
        set columns=140
        set lines=43
        winpos 300 20
    endif
endif

set foldmethod=syntax
set foldlevel=100
set noignorecase
set number
set relativenumber
set ruler
set laststatus=2
set history=100
set autoread
set mouse=a
set nolazyredraw
set so=2
set cmdheight=1
set ignorecase
set incsearch
set magic
set noerrorbells
set novisualbell
set t_vb=
set mat=2
set backspace=start,indent,eol
set updatetime=300
set shortmess+=c
set signcolumn=yes
set ttimeout
set listchars=tab:»■,trail:■
set list
if !has('nvim')
    set wildmode=longest:list
endif

"special file type settings
autocmd Filetype vhdl,verilog setlocal shiftwidth=2
autocmd Filetype vhdl,verilog setlocal tabstop=2
autocmd Filetype vhdl,verilog setlocal softtabstop=2
autocmd Filetype cmake setlocal shiftwidth=2
autocmd Filetype cmake setlocal tabstop=2
autocmd Filetype cmake setlocal softtabstop=2
autocmd Filetype yaml setlocal shiftwidth=2
autocmd Filetype yaml setlocal tabstop=2
autocmd Filetype yaml setlocal softtabstop=2
autocmd BufNewFile,BufRead *.txt setlocal wrap
autocmd BufNewFile,BufRead *.log* setlocal wrap
autocmd BufNewFile,BufRead *.launch set filetype=xml
autocmd BufNewFile,BufRead *.log* set filetype=log
autocmd BufNewFile,BufRead .*rc set filetype=sh

"restore cursor to file position in previous editing session
set viminfo='10,\"100,:20,@20,%

"plugin usage control
let b:UseGit = 0
let b:UseCoc = 0
if executable('git')
    let b:UseGit = 1
endif
if executable('clangd') && executable('node')
    let b:UseCoc = 1
endif

"config vim-plug
if b:IsWin == 1
    silent! call plug#begin('d:\edit\vimfiles\plugged')
else
    silent! call plug#begin('~/.vim/plugged')
endif
Plug 'easymotion/vim-easymotion'
Plug 'tpope/vim-surround'
Plug 'tpope/vim-repeat'
Plug 'tpope/vim-commentary'
Plug 'tpope/vim-unimpaired'
Plug 'tpope/vim-rsi'
Plug 'tpope/vim-speeddating'
Plug 'tpope/vim-endwise'
Plug 'vim-airline/vim-airline'
Plug 'vim-airline/vim-airline-themes'
Plug 'mattn/emmet-vim'
Plug 'jiangmiao/auto-pairs'
Plug 'andymass/vim-matchup'
Plug 'Yggdroot/indentLine'
Plug 'skywind3000/vim-terminal-help'
Plug 'godlygeek/tabular'
Plug 'iamcco/markdown-preview.nvim', {'do':{-> mkdp#util#install()}, 'for':['markdown', 'vim-plug']}
Plug 'lilydjwg/fcitx.vim'
Plug 'mg979/vim-visual-multi', {'branch':'master'}
Plug '907th/vim-auto-save'
Plug 'lifepillar/vim-solarized8'
Plug 'preservim/nerdtree'
Plug 'EdenEast/nightfox.nvim'
Plug 'sainnhe/gruvbox-material'
Plug 'catppuccin/nvim'
Plug 'joshdick/onedark.vim'
Plug 'sheerun/vim-polyglot'
if has('python') || has('python3')
    Plug 'Yggdroot/LeaderF', {'do':'./install.sh'}
endif
if b:UseGit == 1
    Plug 'tpope/vim-fugitive'
    Plug 'airblade/vim-gitgutter'
endif
if b:UseCoc == 1
    Plug 'neoclide/coc.nvim', {'branch':'release'}
endif
if has('nvim')
    Plug 'hiphish/rainbow-delimiters.nvim'
    Plug 'folke/tokyonight.nvim', {'branch':'main'}
    if b:IsWin == 0
        Plug 'nvim-treesitter/nvim-treesitter', {'do':':TSUpdate'}
    endif
    Plug 'mtdl9/vim-log-highlighting'
else
    Plug 'luochen1990/rainbow'
    Plug 'terryma/vim-expand-region'
    Plug 'kana/vim-textobj-user'
    Plug 'kana/vim-textobj-entire'
    Plug 'kana/vim-textobj-line'
    Plug 'kana/vim-textobj-fold'
    Plug 'kana/vim-textobj-indent'
    if b:UseCoc == 0
        Plug 'kana/vim-textobj-function', {'for':['c', 'cpp', 'vim', 'java']}
    endif
    Plug 'kana/vim-textobj-syntax'
    Plug 'kana/vim-textobj-datetime'
    Plug 'kana/vim-textobj-underscore'
    Plug 'sgur/vim-textobj-parameter'
    Plug 'vim-scripts/LargeFile'
endif
silent! call plug#end()

""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => highlight and colors
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
syntax enable
set synmaxcol=5000
syntax sync minlines=1000
set hlsearch
"set cursorline
"set cursorcolumn
set background=dark
if !has('gui_running')
    set t_Co=256
endif
if has('termguicolors')
    set termguicolors
endif
if has('nvim') || (has('patch-8.2.0890') && has('lua'))
    " colorscheme tokyonight-storm
    " let g:airline_theme = 'onedark'

    " colorscheme nordfox
    " let g:airline_theme = 'onedark'

    colorscheme catppuccin-frappe
    let g:airline_theme = 'catppuccin'
    highlight Cursor guifg=#292c3c guibg=#f2d5cf

    " colorscheme onedark
    " let g:airline_theme = 'onedark'
    " let g:onedark_terminal_italics = 1

    " colorscheme gruvbox-material
    " let g:airline_theme = 'gruvbox_material'
    " let g:gruvbox_material_better_performance = 1
    " let g:gruvbox_material_enable_bold = 1
    " let g:gruvbox_material_enable_italic = 1
    " let g:gruvbox_material_diagnostic_text_highlight = 1
    " let g:gruvbox_material_diagnostic_line_highlight = 1
    " let g:gruvbox_material_dim_inactive_windows = 1
    " let g:gruvbox_material_disable_italic_comment = 1
else
    colorscheme solarized8
    let g:solarized_extra_hi_groups=1
endif

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => hotkeys
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
if $TMUX != ''
    set ttimeoutlen=30
elseif &ttimeoutlen > 80 || &ttimeoutlen <= 0
    set ttimeoutlen=80
endif
let mapleader="\<space>"
noremap <c-z> <nop>
noremap <silent><bs> :nohlsearch<cr>
noremap <silent><leader>d :bdelete!<cr>
noremap <silent><leader>q :qa<cr>
noremap <silent><leader>w :w<cr>
noremap <silent><m-t> :e ~/new<cr>
noremap <silent><m-n> :bnext<cr>
noremap <silent><m-p> :bprevious<cr>
noremap <silent><m-h> <c-w>h
noremap <silent><m-j> <c-w>j
noremap <silent><m-k> <c-w>k
noremap <silent><m-l> <c-w>l
noremap <silent><m-o> <c-w>o
noremap <silent><m-c> <c-w>c
noremap <silent><m-s> <c-w>s
noremap <silent><m-v> <c-w>v
noremap <silent><m-+> <c-w>+
noremap <silent><m-_> <c-w>-
noremap <silent><m->> <c-w>>
noremap <silent><m-<> <c-w><
noremap <silent><m-r> :set wrap<cr>
noremap <silent><m-s-r> :set nowrap<cr>
if b:IsWin == 1
    if has('nvim')
        noremap <silent><leader>e :e d:\edit\vimfiles\init.vim<cr>
    else
        noremap <silent><leader>e :e d:\edit\vimfiles\vimrc<cr>
    endif
else
    noremap <silent><leader>e :e ~/.vim/vimrc<cr>
endif
inoremap <c-cr> <c-o>o
inoremap <s-cr> <c-o>O
inoremap <c-k> <c-o>d$
inoremap <c-bs> <c-u>

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => plugin settings
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"config treesitter
if has('nvim') && b:IsWin == 0
    lua require('treesitter')
endif

"config neovide
if exists('g:neovide')
    let g:neovide_scale_factor = 1.0
    set guifont=Maple\ Mono\ Normal\ NF\ CN:h10:#e-subpixelantialias:#h-full
    let g:neovide_remember_window_size=v:true
endif

"config auto save
let g:auto_save = 0
let g:auto_save_silent = 1

"nerdtree config
nnoremap <silent><leader>n :NERDTreeFocus<cr>

"matchup configs
let g:matchup_surround_enabled = 1
let g:matchup_matchparen_deferred = 1
let g:matchup_matchparen_hi_surround_always = 1
autocmd Filetype verilog let b:match_words = '\<begin\>:\<end\>,' . '\<case\>:\<endcase\>,' . '\<fork\>:join\>,'
    \ . '\<module\>:\<endmodule\>,' . '\<funtion\>:\<endfunction\>,' . '\<task\>:\<endtask\>,' . '\<`ifdef\>:\<`endif\>'
autocmd Filetype python let b:match_words = '\<try\>:\<except\>:\<finally\>'
" nnoremap <silent><c-p> :MatchupWhereAmI<cr>

"indentLine config
let g:indentLine_char_list = ['|', '¦', '┆', '┊']
let g:indentLine_setColors = 1
let g:indentLine_concealcursor = 'nc'
let g:indentLine_conceallevel = 2

"tabular config
if exists(':Tabularize')
    nnoremap <silent><leader>a= :Tabularize /=<cr>
    vnoremap <silent><leader>a= :Tabularize /=<cr>
    nnoremap <silent><leader>a: :Tabularize /:\zs<cr>
    vnoremap <silent><leader>a: :Tabularize /:\zs<cr>
    nnoremap <silent><leader>a| :Tabularize /|<cr>
    vnoremap <silent><leader>a| :Tabularize /|<cr>
endif

"vim-cpp-enhanced-highlight config
let g:cpp_class_scope_highlight = 1
let g:cpp_member_variable_highlight = 1
let g:cpp_class_decl_highlight = 1
let g:cpp_posix_standard = 1
let g:cpp_experimental_simple_template_highlight = 1
let g:cpp_concepts_highlight = 1
let g:cpp_no_function_highlight = 0

"python-syntax highlight config
let g:python_highlight_all = 1

"config comment string for commentary
autocmd FileType apache setlocal commentstring=#\ %s
autocmd FileType cmake setlocal commentstring=#\ %s
autocmd FileType c,cpp setlocal commentstring=//\ %s

"emmet config
let g:user_emmet_leader_key = '<m-y>'

"markdown preview config
function OpenMarkdownPreview (url)
    execute "silent ! firefox --new-tab " . a:url
endfunction
let g:mkdp_auto_close = 0
let g:mkdp_browser = '/usr/bin/firefox'
let g:mkdp_browserfunc = 'OpenMarkdownPreview'
inoremap <silent><f8> <plug>MarkdownPreviewToggle
nnoremap <silent><f8> <plug>MarkdownPreviewToggle

"config auto-pairs
let g:AutoPairs = {'(':')', '[':']', '{':'}',"'":"'",'"':'"'}
" let g:AutoPairs['<']='>'
" let b:AutoPairs = g:AutoParis
let g:AutoPairsShortcutToggle = '<c-m-p>'
let g:AutoPairsShortcutFastWrap = '<m-e>'
let g:AutoPairsShortcutJump = '<c-m-n>'
let g:AutoPairsMapBS = 1
let g:AutoPairsMapCh = 1
let g:AutoPairsMapCR = 1
let g:AutoPairsCenterLine = 0
let g:AutoPairsMapSpace = 1
let g:AutoPairsFlyMode = 0
let g:AutoPairsShortcutBackInsert = '<c-m-b>'
let g:AutoPairsMultilineClose = 1
au FileType html let b:AutoPairs = AutoPairsDefine({'<!--':'-->'},['{'])
au FileType php let b:AutoPairs = AutoPairsDefine({'<?':'?>','<?php':'?>'})

"config vim visual multi
let g:VM_leader = '<c-\>'
let g:VM_mouse_mappings = 1
let g:VM_maps = {}
let g:VM_maps['Find Under'] = '<c-m>'
let g:VM_maps['Find Subword Under'] = '<c-m>'
let g:VM_maps['Add Cursor Down'] = '<c-j>'
let g:VM_maps['Add Cursor Up'] = '<c-k>'
let g:VM_maps['Select h'] = '<c-h>'
let g:VM_maps['Select l'] = '<c-l>'
let g:VM_maps['Mouse Cursor'] = '<C-LeftMouse>'
let g:VM_maps['Mouse Word'] = '<C-RightMouse>'
let g:VM_maps['Mouse Column'] = '<M-C-RightMouse>'

"config airline
let g:airline#extensions#tabline#enabled = 1
let g:airline#extensions#tabline#buffer_nr_show = 1
let g:airline#extensions#tabline#buffer_nr_format = '%s:'
let g:airline#extensions#tabline#formatter = 'unique_tail'
let g:airline_powerline_fonts = 1
if !exists('g:airline_symbols')
    let g:airline_symbols = {}
endif
let g:airline_left_sep = ''
let g:airline_left_alt_sep = ''
let g:airline_right_sep = ''
let g:airline_right_alt_sep = ''
let g:airline_symbols.branch = ''
let g:airline_symbols.readonly = ''
let g:airline_symbols.linenr = '☰'
let g:airline_symbols.maxlinenr = ''
let g:airline_symbols.dirty='⚡'
if b:UseCoc == 1
    let g:airline#extensions#coc#enabled = 0
    let airline#extensions#coc#error_symbol = 'Error:'
    let airline#extensions#coc#warning_symbol = 'Warning:'
    let airline#extensions#coc#stl_format_err = '%E{[%e(#%fe)]}'
    let airline#extensions#coc#stl_format_warn = '%W{[%w(#%fw)]}'
endif

"config easy-motion
let g:EasyMotion_smartcase = 1
let g:EasyMotion_use_smartsign_us = 1
noremap \ <plug>(easymotion-prefix)
noremap \l <plug>(easymotion-lineforward)
noremap \h <plug>(easymotion-linebackward)
inoremap <m-\> <c-o><plug>(easymotion-prefix)
inoremap <m-\>l <c-o><plug>(easymotion-lineforward)
inoremap <m-\>h <c-o><plug>(easymotion-linebackward)
inoremap <m-\>f <c-o><plug>(easymotion-f)
inoremap <m-\>F <c-o><plug>(easymotion-F)
inoremap <m-\>t <c-o><plug>(easymotion-t)
inoremap <m-\>T <c-o><plug>(easymotion-T)
inoremap <m-\>w <c-o><plug>(easymotion-w)
inoremap <m-\>W <c-o><plug>(easymotion-W)
inoremap <m-\>b <c-o><plug>(easymotion-b)
inoremap <m-\>B <c-o><plug>(easymotion-B)
inoremap <m-\>e <c-o><plug>(easymotion-e)
inoremap <m-\>E <c-o><plug>(easymotion-E)
inoremap <m-\>ge <c-o><plug>(easymotion-ge)
inoremap <m-\>gE <c-o><plug>(easymotion-gE)
inoremap <m-\>j <c-o><plug>(easymotion-j)
inoremap <m-\>k <c-o><plug>(easymotion-k)
inoremap <m-\>n <c-o><plug>(easymotion-n)
inoremap <m-\>N <c-o><plug>(easymotion-N)
inoremap <m-\>s <c-o><plug>(easymotion-s)
inoremap <m-\>l <c-o><plug>(easymotion-lineforward)
inoremap <m-\>h <c-o><plug>(easymotion-linebackward)

"rainbow config
let g:rainbow_active = 1
let g:rainbow_conf = {
    \ 'guifgs': ['royalblue3', 'darkorange3', 'seagreen3', 'firebrick'],
    \ 'ctermfgs': ['lightblue', 'lightyellow', 'lightcyan', 'lightmagenta'],
    \ 'operators': '_,_',
    \ 'parentheses': ['start=/(/ end=/)/ fold', 'start=/\[/ end=/\]/ fold', 'start=/{/ end=/}/ fold'],
    \ 'separately': {
        \ '*': {},
        \ 'tex': {
            \ 'parentheses': ['start=/(/ end=/)/', 'start=/\[/ end=/\]/'],
        \ },
        \ 'lisp': {
            \ 'guifgs': ['royalblue3', 'darkorange3', 'seagreen3', 'firebrick', 'darkorchid3'],
        \ },
        \ 'vim': {
            \ 'parentheses': ['start=/(/ end=/)/', 'start=/\[/ end=/\]/', 'start=/{/ end=/}/ fold', 'start=/(/ end=/)/ containedin=vimFuncBody', 'start=/\[/ end=/\]/ containedin=vimFuncBody', 'start=/{/ end=/}/ fold containedin=vimFuncBody'],
        \ },
        \ 'html': {
            \ 'parentheses': ['start=/\v\<((area|base|br|col|embed|hr|img|input|keygen|link|menuitem|meta|param|source|track|wbr)[ >])@!\z([-_:a-zA-Z0-9]+)(\s+[-_:a-zA-Z0-9]+(\=("[^"]*"|'."'".'[^'."'".']*'."'".'|[^ '."'".'"><=`]*))?)*\>/ end=#</\z1># fold'],
        \ },
        \ 'css': 0,
        \ 'nerdtree': 0,
    \ }
\ }

"LeaderF config
let g:Lf_HideHelp = 1
let g:Lf_UseCache = 0
let g:Lf_ShowRelativePath = 0
let g:Lf_UseVersionControlTool = 0
let g:Lf_IgnoreCurrentBufferName = 1
let g:Lf_WindowPosition = 'bottom'
let g:Lf_WindowHeight = 0.3
let g:Lf_RootMarkers = ['.project', '.root', '.svn', '.git', '.hg']
let g:Lf_WorkingDirectoryMode = 'Ac'
let g:Lf_CacheDirectory = expand('~/.cache')
let g:Lf_StlColorscheme = 'onedark'
let g:Lf_StlSeparator = {'left': '', 'right': ''}
let g:Lf_PreviewResult = {'File':0, 'Buffer':0, 'Mru':0, 'Tag':0, 'BufTag':0, 'Function':0, 'Line':0, 'Colorscheme':1, 'Rg':0, 'Gtags':0}
let g:Lf_PreviewInPopup = 1
let g:Lf_PreviewHorizontalPosition = 'center'
let g:Lf_PreviewPopupWidth = 120
let g:Lf_ShowDevIcons = 1
let g:Lf_DevIconsFont = 'Maple Mono Normal NF CN:h10'
let g:lf_WildIgnore = {
    \ 'dir': ['img','.svn','.git','.hg','.vscode','build','.idea','cmake-build-debug','venv'],
    \ 'file': ['run.*','*.png','*.sw?','~$*','*.bak','*.exe','*.o','*.ko','*.so','*.py[co]']
\ }
let g:Lf_NormalMap = {
    \ "File":   [["<esc>", ':exec g:Lf_py "fileExplManager.quit()"<cr>']],
    \ "Buffer": [["<esc>", ':exec g:Lf_py "bufExplManager.quit()"<cr>']],
    \ "Mru":    [["<esc>", ':exec g:Lf_py "mruExplManager.quit()"<cr>']],
    \ "Tag":    [["<esc>", ':exec g:Lf_py "tagExplManager.quit()"<cr>']],
    \ "Function":    [["<esc>", ':exec g:Lf_py "functionExplManager.quit()"<cr>']],
    \ "Colorscheme":    [["<esc>", ':exec g:Lf_py "colorschemeExplManager.quit()"<cr>']],
\ }
let g:Lf_ShortcutF = '<leader>p'
let g:Lf_ShortcutB = '<leader><tab>'
noremap <leader>m :LeaderfMru<cr>
noremap <leader>l :LeaderfLine<cr>
if executable('rg')
    noremap <leader>s :Leaderf rg<cr>
    noremap <leader>rw :<c-u><c-r>=printf("Leaderf! rg -F %s ", expand("<cword>"))<cr><cr>
    noremap <leader>rb :<c-u><c-r>=printf("Leaderf! rg --current-buffer -F %s ", expand("<cword>"))<cr><cr>
    xnoremap <leader>rv :<c-u><c-r>=printf("Leaderf! rg -F %s ", leaderf#Rg#visual())<cr><cr>
    noremap <leader>rf :<c-u><c-r>=printf("Leaderf! rg ")<cr>
    noremap <leader>ro :<c-u>Leaderf! rg --recall<cr>
    noremap <silent>]r :<c-u>Leaderf! rg --next<cr>
    noremap <silent>[r :<c-u>Leaderf! rg --previous<cr>
endif
if executable('ctags')
    let g:Lf_Gtagslabel = 'new-ctags'
    let g:Lf_CtagsFuncOpts = {'c':'--c-kinds=+px', 'c++':'--c++-kinds=+px'}
    let g:Lf_GtagsAutoGenerate = 0
    noremap <leader>f :LeaderfFunction<cr>
    noremap <leader>t :LeaderfBufTag<cr>
    " noremap <leader>gr :<c-u><c-r>=printf("Leaderf! gtags -r %s --auto-jump", expand("<cword>"))<cr><cr>
    " noremap <leader>gd :<c-u><c-r>=printf("Leaderf! gtags -d %s --auto-jump", expand("<cword>"))<cr><cr>
    " noremap <leader>gs :<c-u><c-r>=printf("Leaderf! gtags -s %s --auto-jump", expand("<cword>"))<cr><cr>
    " noremap <leader>gg :<c-u><c-r>=printf("Leaderf! gtags -g %s --auto-jump", expand("<cword>"))<cr><cr>
    " noremap <leader>gu :<c-u><c-r>=printf("Leaderf! gtags --update")<cr><cr>
    " noremap <leader>gc :<c-u><c-r>=printf("Leaderf! gtags --recall %s", "")<cr><cr>
    " noremap <leader>gn :<c-u><c-r>=printf("Leaderf gtags --next %s", "")<cr><cr>
    " noremap <leader>gp :<c-u><c-r>=printf("Leaderf gtags --previous %s", "")<cr><cr>
endif

"coc.nvim config
if b:UseCoc == 1
    let b:coc_root_patterns = ['.project', '.root', '.svn', '.git', '.hg']
    let b:coc_diagnostic_info = {'error': 1, 'warning': 1, 'information': 1, 'hint': 1}

    " Use tab for trigger completion with characters ahead and navigate.
    " NOTE: Use command ':verbose imap <tab>' to make sure tab is not mapped by
    " other plugin before putting this into your config.
    inoremap <silent><expr><tab>
            \ coc#pum#visible() ? coc#pum#next(1) :
            \ CheckBackspace() ? "\<tab>" :
            \ coc#refresh()
    inoremap <silent><expr><s-tab> coc#pum#visible() ? coc#pum#prev(1) : "\<c-h>"

    " Make <cr> to accept selected completion item or notify coc.nvim to format
    " <c-g>u breaks current undo, please make your own choice.
    inoremap <silent><expr><cr> coc#pum#visible() ? coc#pum#confirm()
                                  \: "\<c-g>u\<cr>\<c-r>=coc#on_enter()\<cr>"

    function! CheckBackspace() abort
      let col = col('.') - 1
      return !col || getline('.')[col - 1]  =~# '\s'
    endfunction

    " Use <m-space> to trigger completion.
    inoremap <silent><expr><m-space> coc#refresh()

    " Use `[g` and `]g` to navigate diagnostics
    " Use `:CocDiagnostics` to get all diagnostics of current buffer in location list.
    nnoremap <silent>[g <plug>(coc-diagnostic-prev)
    nnoremap <silent>]g <plug>(coc-diagnostic-next)

    " GoTo code navigation.
    nnoremap <silent><leader>cd <plug>(coc-definition)
    nnoremap <silent><leader>cl <plug>(coc-declaration)
    nnoremap <silent><leader>ct <plug>(coc-type-definition)
    nnoremap <silent><leader>ci <plug>(coc-implementation)
    nnoremap <silent><leader>cr <plug>(coc-references)

    " Use cp to show documentation in preview window.
    nnoremap <silent><leader>ck :call ShowDocumentation()<cr>

    function! ShowDocumentation()
      if CocAction('hasProvider', 'hover')
        call CocActionAsync('doHover')
      else
        call feedkeys('K', 'in')
      endif
    endfunction

    " Highlight the symbol and its references when holding the cursor.
    autocmd CursorHold * silent call CocActionAsync('highlight')

    " Symbol renaming
    nnoremap <silent><leader>cn <plug>(coc-rename)

    " Formatting selected code.
    xnoremap <silent><leader>cf <plug>(coc-format-selected)
    nnoremap <silent><leader>cf <plug>(coc-format-selected)

    augroup mygroup
        autocmd!
        " Setup formatexpr specified filetype(s).
        autocmd FileType typescript,json setl formatexpr=CocAction('formatSelected')
        " Update signature help on jump placeholder.
        autocmd User CocJumpPlaceholder call CocActionAsync('showSignatureHelp')
    augroup end

    " Applying codeAction to the selected region.
    " Example: `<leader>caap` for current paragraph
    xnoremap <silent><leader>av <plug>(coc-codeaction-selected)
    nnoremap <silent><leader>av <plug>(coc-codeaction-selected)

    " Remap keys for applying code actions at the cursor position
    nnoremap <silent><leader>aw <plug>(coc-codeaction-cursor)
    " Remap keys for apply code actions affect whole buffer
    nnoremap <silent><leader>af <plug>(coc-codeaction-source)
    " Apply the most preferred quickfix action to fix diagnostic on the current line
    nnoremap <silent><leader>ac <plug>(coc-fix-current)

    " Remap keys for applying refactor code actions
    nnoremap <silent><leader>ar <plug>(coc-codeaction-refactor)
    xnoremap <silent><leader>as <plug>(coc-codeaction-refactor-selected)
    nnoremap <silent><leader>as <plug>(coc-codeaction-refactor-selected)

    " Run the Code Lens action on the current line.
    nnoremap <silent><leader>al <Plug>(coc-codelens-action)

    " Map function and class text objects
    " NOTE: Requires 'textDocument.documentSymbol' support from the language server.
    xnoremap if <plug>(coc-funcobj-i)
    onoremap if <plug>(coc-funcobj-i)
    xnoremap af <plug>(coc-funcobj-a)
    onoremap af <plug>(coc-funcobj-a)
    xnoremap ic <plug>(coc-classobj-i)
    onoremap ic <plug>(coc-classobj-i)
    xnoremap ac <plug>(coc-classobj-a)
    onoremap ac <plug>(coc-classobj-a)

    " Remap <c-f> and <c-b> for scroll float windows/popups.
    if has('nvim-0.4.0') || has('patch-8.2.0750')
        nnoremap <silent><nowait><expr><c-f> coc#float#has_scroll() ? coc#float#scroll(1) : "\<c-f>"
        nnoremap <silent><nowait><expr><c-b> coc#float#has_scroll() ? coc#float#scroll(0) : "\<c-b>"
        inoremap <silent><nowait><expr><c-f> coc#float#has_scroll() ? "\<c-r>=coc#float#scroll(1)\<cr>" : "\<right>"
        inoremap <silent><nowait><expr><c-b> coc#float#has_scroll() ? "\<c-r>=coc#float#scroll(0)\<cr>" : "\<left>"
        vnoremap <silent><nowait><expr><c-f> coc#float#has_scroll() ? coc#float#scroll(1) : "\<c-f>"
        vnoremap <silent><nowait><expr><c-b> coc#float#has_scroll() ? coc#float#scroll(0) : "\<c-b>"
    endif

    " Use ctrl-s for selections ranges.
    " Requires 'textDocument/selectionRange' support of language server.
    nnoremap <silent><c-s> <plug>(coc-range-select)
    xnoremap <silent><c-s> <plug>(coc-range-select)

    " Add `:Format` command to format current buffer.
    command! -nargs=0 Format :call CocAction('format')

    " Add `:Fold` command to fold current buffer.
    command! -nargs=? Fold :call CocAction('fold', <f-args>)

    " Add `:OR` command for organize imports of the current buffer.
    command! -nargs=0 OR :call CocAction('runCommand', 'editor.action.organizeImport')

    " Add (Neo)Vim's native statusline support.
    " NOTE: Please see `:h coc-status` for integrations with external plugins that
    " provide custom statusline: lightline.vim, vim-airline.
    set statusline^=%{coc#status()}%{get(b:,'coc_current_function','')}

    " Mappings for CoCList
    " Show all diagnostics.
    nnoremap <silent><nowait><leader>od :<c-u>CocList diagnostics<cr>
    " Manage extensions.
    nnoremap <silent><nowait><leader>oe :<c-u>CocList extensions<cr>
    " Show commands.
    nnoremap <silent><nowait><leader>oc :<c-u>CocList commands<cr>
    " Find symbol of current document.
    nnoremap <silent><nowait><leader>oo :<c-u>CocList outline<cr>
    " Search workspace symbols.
    nnoremap <silent><nowait><leader>os :<c-u>CocList -I symbols<cr>
    " Do default action for next item.
    nnoremap <silent><nowait><m-]> :<c-u>CocNext<cr>
    " Do default action for previous item.
    nnoremap <silent><nowait><m-[> :<c-u>CocPrev<cr>
    " Resume latest coc list.
    nnoremap <silent><nowait><leader>co :<c-u>CocListResume<cr>
endif

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => functions
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"ToggleHexMode function, toggles hex mode and normal mode
let s:HexModeOn = "N"
function! ToggleHexMode()
    if s:HexModeOn == "Y"
        %!xxd -r
        let s:HexModeOn = "N"
    else
        %!xxd
        let s:HexModeOn = "Y"
    endif
endfunction

"ToggleDiffMode function, toggles diff mode and normal mode
let s:DiffModeOn = "N"
function! ToggleDiffMode()
    if s:DiffModeOn == "N"
        diffthis
        let s:DiffModeOn = "Y"
    else
        diffoff
        let s:DiffModeOn = "N"
    endif
endfunction
